﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvcEngine.Blog.Models.Entities;
using MvcEngine.Blog.Repositories;
using MvcEngine.Core;
using MvcEngine.Core.Helpers;
using MvcEngine.Core.Repositories;
using MvcEngine.Blog.Components.Services;
using MvcEngine.Core.Utils;
using MvcEngine.Core.Base;

namespace MvcEngine.Blog.Managers
{
    public class BlogManager : BaseManager, IBlogManager
    {
        private readonly IBlogRepository blogRepository = null;

        public BlogManager(IBlogRepository blogRepository)
        {
            this.blogRepository = blogRepository;
        }

        public static IBlogManager Current
        {
            get { return IoC.Resolve<IBlogManager>(); }
        }

        public BlogData GetBlogByPage(Guid pageId)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.BlogPage, pageId), BlogCacheKeys.BlogCategory,
                () =>
                {
                    var blog = blogRepository.GetByPage(pageId);
                    ConvertXmlToProperties(blog);
                    return blog;
                });
        }

        public IList<BlogData> GetBlogs()
        {
            return CacheManager.Current.FromCache(CacheUtils.MakeCacheKey(BlogCacheKeys.Blogs, CacheKeys.Site), BlogCacheKeys.BlogCategory,
                () =>
                {
                    var blogs = blogRepository.GetAll(SiteContext.Current.Site.Id);
                    foreach (var item in blogs)
                    {
                        ConvertXmlToProperties(item);
                    }
                    return blogs;
                });
        }

        public BlogData GetBlog(Guid blogId)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.BlogId, blogId), BlogCacheKeys.BlogCategory,
                () =>
                {
                    var blog = blogRepository.Get(blogId);
                    ConvertXmlToProperties(blog);
                    return blog;
                });
        }

        public BlogData GetBlog(string blogName)
        {
            return CacheManager.Current.FromCache(string.Format(BlogCacheKeys.BlogName, blogName), BlogCacheKeys.BlogCategory,
                () =>
                {
                    var blog = blogRepository.Get(blogName);
                    ConvertXmlToProperties(blog);
                    return blog;
                });
        }

        public BlogData GetCurrentBlog()
        {
            return GetBlogByPage(SiteContext.Current.CurrentPage.Id);
        }

        public void Save(BlogData blog)
        {
            Guard.ThrowIfEmptyGuid(blog.PageId, "PageId can't be empty.");
            using (var unitOfWork = UnitOfWorkHelper.Get())
            {
                var oldItem = blogRepository.GetByPage(blog.PageId);
                if (oldItem != null)
                {
                    oldItem.ModifiedDate = DateTime.Now;
                    oldItem.Xml = blog.Fields;
                    blogRepository.Update(oldItem);
                }
                else
                {
                    blog.ModifiedDate = DateTime.Now;
                    blog.CreatedDate = DateTime.Now;
                    blog.Xml = blog.Fields;
                    blogRepository.Add(blog);
                }
                unitOfWork.Commit();
            }
            CacheManager.Current.ClearCache(BlogCacheKeys.BlogCategory);
        }
    }
}
